Skip to content

fix: hydrate proxies from workspace on fresh origins#200

Merged
walterlow merged 36 commits intostagingfrom
develop
Apr 19, 2026
Merged

fix: hydrate proxies from workspace on fresh origins#200
walterlow merged 36 commits intostagingfrom
develop

Conversation

@walterlow
Copy link
Copy Markdown
Owner

Summary

  • On a new deployment origin OPFS has no proxies/ directory yet, so loadExistingProxies returned early and never reached the workspace-folder fallback — proxies in the user's workspace folder were invisible on branch/preview URLs. Create the OPFS dir with { create: true } so the cross-origin hydration path always runs.
  • Switch COEP from require-corp to credentialless: still enables SharedArrayBuffer (WebCodecs, transformers.js WASM threading) but stops blocking cross-origin no-credential subresources like vercel.live's preview feedback widget.

Note: this PR also carries the batch of develop commits that had already landed since the last staging sync (scene browser, caption work, preview/skim fixes, etc.).

Test plan

  • Visit a fresh branch preview URL in an incognito window, pick E:\FreeCutProjects as workspace, confirm proxies hydrate into the media library.
  • Confirm no ERR_BLOCKED_BY_RESPONSE.NotSameOriginAfterDefaultedToSameOriginByCoep in console on branch previews.
  • Sanity check SharedArrayBuffer-dependent features (export, transcription) still work.

- Add media captioning service for generating captions from transcriptions
- Integrate caption insertion into timeline as text items
- Add caption storage layer in workspace-fs
- Update media library card UI to show caption generation status
- Add captions to project schema and type definitions
- Support replacing existing captions on timeline
- Handle linked items when inserting captions (dissolve/transitions)
Motion labels at scene-cut frames reflected splice transients, not scene
content, so queries like "slow pan right" ranked unrelated static shots.
Optical-flow scene-cut detection still powers scene splitting.

Also fix "pink" ranking: move pink Lab to (70, 50, -8) so it stops
overlapping warm skin tones, split coral/salmon into its own family,
and gate chromatic families on palette chroma + hue so gray/beige
entries can't score as pink under ∆E 2000.
Add a palette-to-palette similarity ranker that scores scenes by
weighted-mean ∆E 2000 against a reference palette, plus two entry
points: clicking a scene-row swatch searches by the nearest color
family, and a hover palette icon pins the whole palette as the
reference. An active reference shows as a chip in the search input
and disables the query field until cleared.
Swap the search input for a weighted k-means palette of the library's
dominant colors when Color mode is on; clicking a swatch pins it as
the reference for palette-similarity ranking. Each row also surfaces
its own palette swatches in color mode so users can pivot directly
from a result. Move the Scenes view toggle next to Import, hide the
media-library filter row while the scene browser is mounted, drop the
now-redundant back arrow, and fix the scrollbar overlap by forcing
Radix's inner viewport wrapper to block layout. Hide the strength bar
when palette-only ranking has no text/image cosines.
- Add list/grid view toggle with responsive thumbnail cards that surface
  the same match signals (strength, badges, palette) as list rows.
- Redesign header as two rows with compact-mode collapsing: Color/Keyword/
  Analyze shrink to icons below 360px, scope picker collapses earlier
  (440px, or 560px when a specific media is scoped) since filenames are
  unbounded.
- Cap library palette at 2 rows with overflow flyout; uniform square
  swatches via auto-fill grid.
- Extract media-analysis-service to own the captions/embeddings/palette
  pipeline with determinate progress + cancel, surfaced via new
  analysisProgress store state driving the library progress bar.
- Preserve scene-browser and media-library Zustand stores across Vite
  HMR via globalThis caching so saves don't wipe panel state.
- Drop the semantic status sub-header (low-value index counts).
Extract media analysis into a dedicated service and add a grid view
for the scene browser with a responsive header that collapses controls
at narrow widths.
On a new deployment origin OPFS had no `proxies/` dir, so `loadExistingProxies`
returned early and never reached the workspace-folder fallback — proxies in
the user's workspace folder were invisible on branch/preview URLs. Create the
OPFS dir with `{ create: true }` so the cross-origin hydration path always runs.

Also switch COEP from `require-corp` to `credentialless`: still enables
SharedArrayBuffer (WebCodecs, transformers.js WASM threading) but stops
blocking cross-origin no-credential subresources like vercel.live's preview
feedback widget.
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Apr 19, 2026

Too many files changed for review. (216 files found, 100 file limit)

@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 19, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
freecut Ready Ready Preview, Comment Apr 19, 2026 7:53am
1 Skipped Deployment
Project Deployment Actions Updated (UTC)
freecut-web Ignored Ignored Apr 19, 2026 7:53am

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 19, 2026

Important

Review skipped

Too many files!

This PR contains 216 files, which is 66 over the limit of 150.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 33048821-9056-4fd4-8877-0716b6577977

📥 Commits

Reviewing files that changed from the base of the PR and between 0d6c30f and 8df382d.

📒 Files selected for processing (216)
  • README.md
  • src/app/state/editor/store.ts
  • src/app/state/editor/types.ts
  • src/config/hotkeys.ts
  • src/features/composition-runtime/utils/audio-decode-cache.ts
  • src/features/composition-runtime/utils/preview-audio-conform.ts
  • src/features/editor/components/audio-meter-panel.tsx
  • src/features/editor/components/editor.test.tsx
  • src/features/editor/components/editor.tsx
  • src/features/editor/components/preview-area.test.tsx
  • src/features/editor/components/preview-area.tsx
  • src/features/editor/components/settings-dialog.tsx
  • src/features/editor/deps/scene-browser-contract.ts
  • src/features/editor/deps/scene-browser.ts
  • src/features/editor/deps/settings-contract.ts
  • src/features/editor/hooks/use-editor-hotkeys.ts
  • src/features/export/utils/canvas-effects.test.ts
  • src/features/export/utils/canvas-effects.ts
  • src/features/export/utils/canvas-item-renderer.ts
  • src/features/export/utils/client-render-engine.ts
  • src/features/media-library/components/background-task-progress.test.tsx
  • src/features/media-library/components/background-task-progress.tsx
  • src/features/media-library/components/compositions-section.tsx
  • src/features/media-library/components/media-card.test.tsx
  • src/features/media-library/components/media-card.tsx
  • src/features/media-library/components/media-info-popover.test.tsx
  • src/features/media-library/components/media-info-popover.tsx
  • src/features/media-library/components/media-library.tsx
  • src/features/media-library/components/transcribe-dialog.test.tsx
  • src/features/media-library/components/transcribe-dialog.tsx
  • src/features/media-library/contracts/timeline.ts
  • src/features/media-library/deps/analysis-contract.ts
  • src/features/media-library/deps/analysis.ts
  • src/features/media-library/deps/composition-runtime-contract.ts
  • src/features/media-library/deps/scene-browser-contract.ts
  • src/features/media-library/deps/scene-browser.ts
  • src/features/media-library/deps/settings-contract.ts
  • src/features/media-library/services/media-analysis-service.test.ts
  • src/features/media-library/services/media-analysis-service.ts
  • src/features/media-library/services/media-captioning-service.ts
  • src/features/media-library/services/media-library-service.ts
  • src/features/media-library/services/media-transcription-service.test.ts
  • src/features/media-library/services/media-transcription-service.ts
  • src/features/media-library/services/proxy-service.ts
  • src/features/media-library/stores/media-delete-actions.test.ts
  • src/features/media-library/stores/media-delete-actions.ts
  • src/features/media-library/stores/media-library-store.ts
  • src/features/media-library/transcription/browser-transcriber.ts
  • src/features/media-library/transcription/lib/bridge.ts
  • src/features/media-library/transcription/registry.test.ts
  • src/features/media-library/transcription/types.ts
  • src/features/media-library/transcription/workers/decoder.worker.ts
  • src/features/media-library/transcription/workers/whisper.worker.ts
  • src/features/media-library/types.ts
  • src/features/media-library/utils/caption-items.test.ts
  • src/features/media-library/utils/caption-items.ts
  • src/features/preview/components/edit-2up-panels.tsx
  • src/features/preview/components/edit-4up-panels.tsx
  • src/features/preview/components/inline-source-preview.tsx
  • src/features/preview/components/rolling-edit-overlay-utils.ts
  • src/features/preview/components/rolling-edit-overlay.test.ts
  • src/features/preview/components/rolling-edit-overlay.tsx
  • src/features/preview/components/source-composition.tsx
  • src/features/preview/components/source-monitor.test.tsx
  • src/features/preview/components/source-monitor.tsx
  • src/features/preview/components/timecode-display.test.tsx
  • src/features/preview/components/timecode-display.tsx
  • src/features/preview/components/use-edit-overlay-panel-prewarm.ts
  • src/features/preview/components/video-preview.sync.test.tsx
  • src/features/preview/components/video-preview.tsx
  • src/features/preview/deps/timeline-utils.ts
  • src/features/preview/hooks/use-preview-capture-bridge.ts
  • src/features/preview/hooks/use-preview-composition-model.ts
  • src/features/preview/hooks/use-preview-render-pump-controller.ts
  • src/features/preview/hooks/use-preview-renderer-controller.ts
  • src/features/preview/utils/edit-overlay-frame-cache.test.ts
  • src/features/preview/utils/edit-overlay-frame-cache.ts
  • src/features/preview/utils/edit-overlay-prewarm-plan.test.ts
  • src/features/preview/utils/edit-overlay-prewarm-plan.ts
  • src/features/preview/utils/preview-constants.test.ts
  • src/features/preview/utils/preview-constants.ts
  • src/features/preview/utils/preview-scrubbing-cache-bridge.test.ts
  • src/features/preview/utils/preview-scrubbing-cache-bridge.ts
  • src/features/preview/utils/scrubbing-cache.test.ts
  • src/features/preview/utils/scrubbing-cache.ts
  • src/features/preview/utils/text-render-guard.test.ts
  • src/features/preview/utils/text-render-guard.ts
  • src/features/project-bundle/schemas/project-schema.ts
  • src/features/projects/hooks/use-project-thumbnail.ts
  • src/features/projects/stores/project-store.ts
  • src/features/scene-browser/components/highlighted-text.tsx
  • src/features/scene-browser/components/library-palette-grid.tsx
  • src/features/scene-browser/components/scene-browser-panel.tsx
  • src/features/scene-browser/components/scene-card.tsx
  • src/features/scene-browser/components/scene-match-badges.tsx
  • src/features/scene-browser/components/scene-palette-swatches.tsx
  • src/features/scene-browser/components/scene-row.tsx
  • src/features/scene-browser/components/scene-search-input.tsx
  • src/features/scene-browser/deps/analysis-contract.ts
  • src/features/scene-browser/deps/analysis.ts
  • src/features/scene-browser/deps/media-library-contract.ts
  • src/features/scene-browser/deps/media-library.ts
  • src/features/scene-browser/deps/settings-contract.ts
  • src/features/scene-browser/deps/settings.ts
  • src/features/scene-browser/deps/storage.ts
  • src/features/scene-browser/hooks/use-caption-thumbnail.ts
  • src/features/scene-browser/hooks/use-library-palette.ts
  • src/features/scene-browser/hooks/use-ranked-scenes.ts
  • src/features/scene-browser/hooks/use-semantic-index.test.tsx
  • src/features/scene-browser/hooks/use-semantic-index.ts
  • src/features/scene-browser/index.ts
  • src/features/scene-browser/stores/scene-browser-store.ts
  • src/features/scene-browser/utils/color-boost.test.ts
  • src/features/scene-browser/utils/color-boost.ts
  • src/features/scene-browser/utils/embeddings-cache.ts
  • src/features/scene-browser/utils/invalidate.ts
  • src/features/scene-browser/utils/lazy-thumb.ts
  • src/features/scene-browser/utils/library-palette.test.ts
  • src/features/scene-browser/utils/library-palette.ts
  • src/features/scene-browser/utils/rank.test.ts
  • src/features/scene-browser/utils/rank.ts
  • src/features/scene-browser/utils/seek.ts
  • src/features/scene-browser/utils/semantic-rank.test.ts
  • src/features/scene-browser/utils/semantic-rank.ts
  • src/features/settings/components/hotkey-editor-sections.ts
  • src/features/settings/stores/settings-store.test.ts
  • src/features/settings/stores/settings-store.ts
  • src/features/timeline/components/timeline-content.test.tsx
  • src/features/timeline/components/timeline-content.tsx
  • src/features/timeline/components/timeline-item/index.tsx
  • src/features/timeline/components/timeline-item/item-context-menu.test.tsx
  • src/features/timeline/components/timeline-item/item-context-menu.tsx
  • src/features/timeline/components/timeline-item/use-timeline-item-actions.ts
  • src/features/timeline/components/timeline-navigator.tsx
  • src/features/timeline/components/timeline-playhead.test.tsx
  • src/features/timeline/components/timeline-playhead.tsx
  • src/features/timeline/contracts/media-library.ts
  • src/features/timeline/contracts/preview.ts
  • src/features/timeline/deps/transcribe-dialog.ts
  • src/features/timeline/hooks/use-rate-stretch.ts
  • src/features/timeline/hooks/use-timeline-drag.ts
  • src/features/timeline/hooks/use-timeline-slip-slide.ts
  • src/features/timeline/hooks/use-timeline-trim.ts
  • src/features/timeline/hooks/use-track-push.ts
  • src/features/timeline/hooks/use-transition-resize.ts
  • src/features/timeline/services/filmstrip-cache.test.ts
  • src/features/timeline/services/filmstrip-cache.ts
  • src/features/timeline/services/filmstrip-memory-state.ts
  • src/features/timeline/services/filmstrip-opfs-storage.ts
  • src/features/timeline/services/filmstrip-storage.ts
  • src/features/timeline/stores/actions/item-actions.linked-items.test.ts
  • src/features/timeline/stores/actions/item-actions.slip-slide.test.ts
  • src/features/timeline/stores/actions/item-actions.ts
  • src/features/timeline/stores/actions/item-edit-actions.ts
  • src/features/timeline/stores/actions/linked-edit.test.ts
  • src/features/timeline/stores/actions/linked-edit.ts
  • src/features/timeline/stores/timeline-persistence.ts
  • src/features/timeline/utils/linked-items.test.ts
  • src/features/timeline/utils/linked-items.ts
  • src/features/timeline/utils/zoom-anchor.test.ts
  • src/features/timeline/utils/zoom-anchor.ts
  • src/features/timeline/workers/filmstrip-extraction-worker.ts
  • src/infrastructure/analysis/index.ts
  • src/infrastructure/storage/cache-version.ts
  • src/infrastructure/storage/index.ts
  • src/infrastructure/storage/workspace-fs/README.template.md
  • src/infrastructure/storage/workspace-fs/ai-outputs/ai-outputs.test.ts
  • src/infrastructure/storage/workspace-fs/ai-outputs/index.ts
  • src/infrastructure/storage/workspace-fs/ai-outputs/io.ts
  • src/infrastructure/storage/workspace-fs/ai-outputs/types.ts
  • src/infrastructure/storage/workspace-fs/captions.ts
  • src/infrastructure/storage/workspace-fs/paths.ts
  • src/infrastructure/storage/workspace-fs/scenes.ts
  • src/infrastructure/storage/workspace-fs/transcripts.test.ts
  • src/infrastructure/storage/workspace-fs/transcripts.ts
  • src/lib/analysis/captioning/lfm-captioning-provider.ts
  • src/lib/analysis/captioning/scene-caption-format.test.ts
  • src/lib/analysis/captioning/scene-caption-format.ts
  • src/lib/analysis/captioning/types.ts
  • src/lib/analysis/embeddings/clip-provider.ts
  • src/lib/analysis/embeddings/clip-worker.ts
  • src/lib/analysis/embeddings/context.test.ts
  • src/lib/analysis/embeddings/context.ts
  • src/lib/analysis/embeddings/create-clip-worker.ts
  • src/lib/analysis/embeddings/create-embeddings-worker.ts
  • src/lib/analysis/embeddings/dominant-colors.ts
  • src/lib/analysis/embeddings/embeddings-provider.ts
  • src/lib/analysis/embeddings/embeddings-worker.ts
  • src/lib/analysis/embeddings/index.ts
  • src/lib/analysis/embeddings/lab-color.test.ts
  • src/lib/analysis/embeddings/lab-color.ts
  • src/lib/analysis/embeddings/types.ts
  • src/lib/analysis/index.ts
  • src/lib/analysis/lfm-scene-worker.ts
  • src/main.tsx
  • src/routes/projects/index.tsx
  • src/shared/components/color-scopes-view.tsx
  • src/shared/state/playback/index.ts
  • src/shared/state/playback/preview-handoff.test.ts
  • src/shared/state/playback/preview-handoff.ts
  • src/shared/state/preview-bridge/store.test.ts
  • src/shared/state/preview-bridge/store.ts
  • src/shared/state/preview-bridge/types.ts
  • src/shared/state/source-player/store.test.ts
  • src/shared/state/source-player/store.ts
  • src/shared/state/source-player/types.ts
  • src/shared/utils/browser-whisper-models.ts
  • src/shared/utils/schedule-after-paint.ts
  • src/shared/utils/transcription-cancellation.ts
  • src/shared/utils/transcription-progress.test.ts
  • src/shared/utils/transcription-progress.ts
  • src/shared/utils/whisper-settings.ts
  • src/types/project.ts
  • src/types/storage.ts
  • src/types/timeline.ts
  • vercel.json

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch develop

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@walterlow walterlow merged commit 97f95ff into staging Apr 19, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant